import os
import subprocess
import datetime
import time
import subprocess
import psutil
from notebook.auth import passwd
import argparse
import shutil
from multiprocessing import Process
import sys
timeout = 20
user_config_str = "c.NotebookApp.notebook_dir = \'{Path}\'"+"\n"+"c.NotebookApp.token = \'{hashed}\'"+"\n"+"c.NotebookApp.port = {port}"
contextList = ["c.NotebookApp.token = u\'{hashed}\'"+"\n","c.NotebookApp.port = {port}"]
command_str = "jupyter notebook --config {configfile}"


#文件#
pythonfile1 = "clean.ipynb" 
pythonfile2 = "ML.ipynb"
pythonfile3 = "Train.ipynb"
config  = "config.py"
portfile = "port.txt"

#路径#
base = "F:\\workspace\\hj\\python\\users\\"
tree_base = "F:\\\\workspace\\\\hj\\\\python\\\\users\\\\"

user_config_path = base+"{user}\\config.py"
user_file_path = base+"{user}"
tree_formart = tree_base+"{user}\\\\tree"
port_file_path = base+"{user}\\port.txt"


        

def update_config(user,context,index):        #return status    index = 1 ←port  index  = 0 ←token
     uConfigStr = user_config_path.format(user = user)
     #print("port : {p}}".format(p = context))
     try:
       lines = open(uConfigStr, 'r').readlines()
       if index == 1:
        lines[index-2]=contextList[index].format(port = context)
       else:
        lines[index-2]=contextList[index].format(hashed = passwd(context))
       open(uConfigStr, 'w').writelines(lines)
       return True
     except:
       s = "update {user} config file failed".format(user = user)
       #print(s)
       return False 

def getpid(port):                             #return current pid
    net_con = psutil.net_connections()
    pid = 0
    for e in net_con:
        if e.laddr.port == port:
            pid=e.pid
            return pid
            #break
    return pid

def search_port():                   #return free port
    ports = range(8888,9999)
    newport=0
    for e in ports:
        idd = getpid(e)
        if idd == 0:
          newport = e
          #print(newport)
          return newport
    return newport    

def create_user_jupyter(user,pwd):       #return 1.status  2.port
   hashed = passwd(pwd)
   hashed = hashed.split("sha1:")[1]
   #print("??"+hashed)
   path = user_file_path.format(user = user)
   tree = tree_formart.format(user = user)
   port = search_port()
   try:
    #print("@")
    os.mkdir(path)
    #print("@")
    shutil.copy(config,path)
    configPath = path+"\\"+config
    os.mkdir(path+"\\"+"tree")
    f = user_file_path.format(user = user)
    shutil.copy(pythonfile1,tree)
    shutil.copy(pythonfile2,tree)
    shutil.copy(pythonfile3,tree)
    shutil.copy(portfile,f)
    s = user_config_str.format(Path=tree,port=port,hashed=hashed)
    with open(configPath, 'a') as f:
      f.write(s)
   except OSError :
     #print("?")
     return False,port,hashed
   return True,port,hashed
   
def get_user_singed_port(user):               #return user's port
     path = user_config_path.format(user=user)
     #print("?")
     lines = open(path, 'r').readlines()
     p=lines[-1].split(" = ")
     #print("?????"+str(p))     
     return p[1]      
      
def shutdown(user,port):
     pid = getpid(port)  
     while pid != 0:    
       process = psutil.Process(pid)
       process.terminate()
       s = "port:{port} has released".format(port = port)
       #print(s)
       time.sleep(0.1)
       pid = getpid(port)
     path =  user_file_path.format(user = user)
     shutil.rmtree(path)
     s = "user:{user} logout".format(user = user)
     #print(s)
     return True     
      
      
#################################

#           Main

#################################
def run_session(user,pwd):       
    #check user path exists
    dirs = user_file_path.format(user = user)
    if not os.path.exists(dirs):
       #创建用户
       c,port,hashed = create_user_jupyter(user,pwd)
       if not c :
         #print("创建用户：{user}失败".format(user = user))
         return
       #print("创建用户：{user}成功, 端口号：{port}".format(user = user, port = port))
       port = get_user_singed_port(user)
       sta = getpid(port)
       while sta != 0 :
          port = search_port()
          # update port
          if update_config(user,port,1):
            s = "update {user} port:{port} ".format(user = user,port = port)
            #print(s)
            sta = getpid(port)
       
       #print(command)
       port = int(get_user_singed_port(user))
       #print(port)
       #time.sleep(20)
       systemcommand = "python t3.py -timeout {timeout} -user {user} -port {port}".format(timeout=timeout,user=user,port=port)
       
       ping = subprocess.Popen(systemcommand, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
       #os.system(systemcommand)
       pid = 0
       while pid==0:
         pid = getpid(port)
       f = open(port_file_path.format(user = user),'w')
       s = "{port}#{hashed}".format(user=user,port=port,hashed=hashed)
       f.write(s)
       f.close()
       print(s)       
    else:
        s = "user:{user} exsits".format(user = user)     
         
        
     
  


if __name__ == '__main__':
    #parser = argparse.ArgumentParser(prog='c.py')
    #parser.add_argument('-action',nargs='+',type=str, default='0', help='0:新建')
    #parser.add_argument('-uid',nargs='+',type=str)
    #parser.add_argument('-pwd',nargs='+',type=str)
    #opt = parser.parse_args()
    #sys.argv[0]
    run_session(sys.argv[1],sys.argv[2])
